package com.fujin.gulimall.search.thread;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @title: ThreadTest2
 * @Author uIn
 * @Date: 2022/2/22 10:17
 * @Version 1.0
 */
public class ThreadTest2 {

    private static ExecutorService service = Executors.newFixedThreadPool(5);

    /**
     * 不指定线程池
     *static CompletableFuture<Void> runAsync(Runnable runnable)
     *
     * 指定某个线程池执行
     *public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
     *  System.out.println("任务执行！！！");
     *         CompletableFuture.runAsync(()->{
     *             System.out.println("线程池任务执行开始!!!");
     *             int i = 10 / 2;
     *             System.out.println("线程池任务执行结束!!!");
     *         },service);
     *   System.out.println("任务结束！！！");
     *
     * 不指定线程池、有返回值
     *public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
     *
     * 指定某个线程池执行、有返回值
     *public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)
     * System.out.println("任务执行！！！");
     *         CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(() -> {
     *             System.out.println("线程池任务执行开始!!!");
     *             int i = 10 / 2;
     *             System.out.println("线程池任务执行结束!!!");
     *             return i;
     *         }, service);
     *         //返回值、但这样还是阻塞的
     * System.out.println(supplyAsync.get());
     * System.out.println("任务结束！！！");
     *
     *
     *  thenRunAsync：无法得到上一步的返回结果，没有返回值
     *      CompletableFuture.supplyAsync(() -> {
     *             System.out.println(Thread.currentThread().getName()+"线程池任务执行开始!!!");
     *             int i = 10 / 2;
     *             System.out.println(Thread.currentThread().getName()+"线程池任务执行结束!!!");
     *             return i;
     *         }, service).thenRunAsync(() -> {
     *             System.out.println("任务2执行了。。。");
     *         }, service);
     *
     *  thenAcceptAsync:  能得到上一步的返回结果，没有返回值
     *      CompletableFuture.supplyAsync(() -> {
     *             System.out.println(Thread.currentThread().getName()+"线程池任务执行开始!!!");
     *             int i = 10 / 2;
     *             System.out.println(Thread.currentThread().getName()+"线程池任务执行结束!!!");
     *             return i;
     *         }, service).thenAcceptAsync(res -> {
     *             //res为上一个任务的返回结果
     *             System.out.println("任务2完成。。。"+res);
     *         });
     *
     *  thenApplyAsync: 能得到上一步的返回结果，有返回值
     *      CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
     *             System.out.println(Thread.currentThread().getName() + "线程池任务执行开始!!!");
     *             int i = 10 / 2;
     *             System.out.println(Thread.currentThread().getName() + "线程池任务执行结束!!!");
     *             return i;
     *         }, service).thenApplyAsync(res -> {
     *             //res为上一个任务的返回结果
     *             System.out.println("任务2完成。。。" + res);
     *             return 10;
     *         });
     *
     *
     *
     *     CompletableFuture<Integer> task01 = CompletableFuture.supplyAsync(() -> {
     *             System.out.println(Thread.currentThread().getName() + "任务1开始!!!");
     *             int i = 10 / 2;
     *             System.out.println(Thread.currentThread().getName() + "任务1结束!!!");
     *             return i;
     *         }, service);
     *
     *         CompletableFuture<String> task02 = CompletableFuture.supplyAsync(() -> {
     *             System.out.println(Thread.currentThread().getName() + "任务1开始!!!");
     *             System.out.println(Thread.currentThread().getName() + "任务1结束!!!");
     *             return "task02";
     *         }, service);
     *
     *      runAfterBothAsync：
     *          //参数1:另外一个任务，参数2:任务3执行的内容，参数3:在某个线程池中执行
     *          task01.runAfterBothAsync(task02,() -> {
     *             //runAfterBothAsync无法得到前面两个任务的返回值，自身也没有返回值
     *             System.out.println("任务3开始执行");
     *         },service);
     *
     *      thenAcceptBothAsync:
     *          //参数1:另外一个任务，参数2:任务3执行的内容，参数3:在某个线程池中执行
     *          task01.thenAcceptBothAsync(task02,(taskOneRes,taskTwoRes) -> {
     *             //taskOneRes为任务1的返回值，taskTwoRes为任务2的返回值
     *             System.out.println("任务1的返回为:"+taskOneRes + "任务2的返回为"+taskTwoRes);
     *         },service);
     *
     *      thenCombineAsync:
     *          //参数1:另外一个任务，参数2:任务3执行的内容，参数3:在某个线程池中执行
     *         task01.thenCombineAsync(task02,(taskOneRes,taskTwoRes) -> {
     *             //taskOneRes为任务1的返回值，taskTwoRes为任务2的返回值
     *             System.out.println("任务1的返回为:"+taskOneRes + "任务2的返回为"+taskTwoRes);
     *             return "这是任务3的返回值";
     *         },service);
     *
     *
     *
     *      runAfterEitherAsync:两个组合任务，其中一个完成任务3就执行，无返回值，无法接收前一个任务返回值
     *          //参数1:另外一个任务，参数2:任务3执行的内容，参数3:在某个线程池中执行
     *          task01.runAfterEitherAsync(task02,() -> {
     *             System.out.println("任务3执行。。。");
     *         },service);
     *
     *      acceptEitherAsync:两个组合任务，其中一个完成任务3就执行，无返回值，可以接收到前一个任务返回值
     *          注意:前两个任务返回值需要相同
     *          //参数1:另外一个任务，参数2:任务3执行的内容，参数3:在某个线程池中执行
     *          task01.acceptEitherAsync(task02,(res) -> {
     *             System.out.println("任务3执行。。。上一条任务返回值为:"+res);
     *         },service);
     *
     *
     *      applyToEitherAsync:两个组合任务，其中一个完成任务3就执行，有返回值，可以接收前一个任务返回值
     *          注意:前两个任务返回值需要相同
     *          //参数1:另外一个任务，参数2:任务3执行的内容，参数3:在某个线程池中执行
     *          task01.applyToEitherAsync(task02,(res) -> {
     *             System.out.println("任务3执行。。。上一条任务返回值为:"+res);
     *             return "这是任务3返回";
     *         },service);
     *
     */

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println(Thread.currentThread().getName()+"任务执行！！！");

        CompletableFuture<Object> task01 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "任务1开始!!!");
            int i = 10 / 2;
            System.out.println(Thread.currentThread().getName() + "任务1结束!!!");
            return i;
        }, service);

        CompletableFuture<Object> task02 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "任务1开始!!!");
            System.out.println(Thread.currentThread().getName() + "任务1结束!!!");
            return "task02";
        }, service);

        task01.applyToEitherAsync(task02,(res) -> {
            System.out.println("任务3执行。。。上一条任务返回值为:"+res);
            return "这是任务3返回";
        },service);

        //参数1:另外一个任务，参数2:任务3执行的内容，参数3:在某个线程池中执行
//        task01.thenCombineAsync(task02,(taskOneRes,taskTwoRes) -> {
//            //taskOneRes为任务1的返回值，taskTwoRes为任务2的返回值
//            System.out.println("任务1的返回为:"+taskOneRes + "任务2的返回为"+taskTwoRes);
//            return "这是任务3的返回值";
//        },service);

//        task01.thenAcceptBothAsync(task02,(taskOneRes,taskTwoRes) -> {
//            //taskOneRes为任务1的返回值，taskTwoRes为任务2的返回值
//            System.out.println("任务1的返回为:"+taskOneRes + "任务2的返回为"+taskTwoRes);
//        },service);

//        task01.runAfterBothAsync(task02,() -> {
//            //runAfterBothAsync无法得到前面两个任务的返回值，自身也没有返回值
//            System.out.println("任务3开始执行");
//        },service);

//        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
//            System.out.println(Thread.currentThread().getName() + "线程池任务执行开始!!!");
//            int i = 10 / 2;
//            System.out.println(Thread.currentThread().getName() + "线程池任务执行结束!!!");
//            return i;
//        }, service).thenApplyAsync(res -> {
//            //res为上一个任务的返回结果
//            System.out.println("任务2完成。。。" + res);
//            return 10;
//        });

//        CompletableFuture.supplyAsync(() -> {
//            System.out.println(Thread.currentThread().getName()+"线程池任务执行开始!!!");
//            int i = 10 / 2;
//            System.out.println(Thread.currentThread().getName()+"线程池任务执行结束!!!");
//            return i;
//        }, service).thenAcceptAsync(res -> {
//            //res为上一个任务的返回结果
//            System.out.println("任务2完成。。。"+res);
//        });

//        CompletableFuture.supplyAsync(() -> {
//            System.out.println(Thread.currentThread().getName()+"线程池任务执行开始!!!");
//            int i = 10 / 2;
//            System.out.println(Thread.currentThread().getName()+"线程池任务执行结束!!!");
//            return i;
//        }, service).thenRunAsync(() -> {
//            System.out.println("任务2执行了。。。");
//        }, service);

//        CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(() -> {
//            try {
//                Thread.sleep(5000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread().getName()+"线程池任务执行开始!!!");
//            int i = 10 / 2;
//            System.out.println(Thread.currentThread().getName()+"线程池任务执行结束!!!");
//            return i;
//        }, service).whenCompleteAsync((r,e) -> {
//            //r为返回值，e为异常信息
//            System.out.println(Thread.currentThread().getName()+"异步执行成功。。。返回结果是:"+r+"异常信息为:"+e);
//        }).exceptionally(throwable -> {
//            //可以感知异常 同时返回一个默认值
//            return 10;
//        });

        //返回值、但这样还是阻塞的
//        System.out.println(supplyAsync.get());
        System.out.println(Thread.currentThread().getName()+"任务结束！！！");
    }

}
